# System
import os
import urllib
import sys

# Boxee
import mc

# Simplejson
import simplejson as json

# GiantBomb Api Interface
import whimai.gb as gb
import whimai.wm as wm

# Variables
default_image = "http://whimais.googlecode.com/svn/plugin%20data/branches/giantbomb%20-%20boxee/icon.png"

settings_url = "http://whimais.googlecode.com/svn/plugin%20data/branches/giantbomb%20-%20boxee/settings.json"
settings_file = os.getcwd() + "/settings.json"

video_file = os.getcwd() + "/video.dat"

def start():
	config = mc.GetApp().GetLocalConfig()
	state = config.GetValue("state")
	
	if state == "justin":
		justin()
	elif state == "bombcast":
		bombcast()
	elif state == "search":
		search(True)
	else:
		video()

def list_down():
	if mc.GetWindow(14000).GetList(100).IsVisible():
		mc.GetWindow(14000).GetControl(100).SetFocus()
	
	elif mc.GetWindow(14000).GetList(200).IsVisible():
		mc.GetWindow(14000).GetControl(200).SetFocus()
		
	else:
		print "NO LIST ACTIVE"

# BombCast
def bombcast():
	mc.ShowDialogWait()
	mc.GetWindow(14000).GetControl(9013).SetVisible(True)
	mc.GetWindow(14000).GetControl(9012).SetVisible(False)
	mc.GetWindow(14000).GetControl(9011).SetVisible(False)
	mc.GetWindow(14000).GetControl(9014).SetVisible(False)
	mc.GetWindow(14000).GetControl(100).SetVisible(True)
	mc.GetWindow(14000).GetControl(200).SetVisible(False)
	mc.GetWindow(14000).GetControl(101).SetVisible(True)
	mc.GetWindow(14000).GetControl(201).SetVisible(False)
	mc.GetWindow(14000).GetList(100).SetContentURL("rss://www.giantbomb.com/podcast-xml/")
	mc.GetWindow(14000).GetLabel(1200).SetLabel("Listen to the craziness that is the bombcast")
	mc.HideDialogWait()	
	mc.GetApp().GetLocalConfig().SetValue("state", "bombcast")

# the live channel
def justin():
	mc.ShowDialogWait()
	mc.GetWindow(14000).GetControl(9014).SetVisible(True)
	mc.GetWindow(14000).GetControl(9012).SetVisible(False)
	mc.GetWindow(14000).GetControl(9011).SetVisible(False)
	mc.GetWindow(14000).GetControl(9013).SetVisible(False)
	
	justin_url = "http://api.justin.tv/api/channel/archives/giantbomb.json?limit=%(lim)s&offset=%(off)s"
	limit = 100
	offset = 0
	done = False
	j_list = []
	
	while done == False:
		s = urllib.urlopen( justin_url%{ 'lim': limit , 'off': offset } )
		tmp = eval( s.read() )
		if len(tmp) is 0:
			done = True
		else:
			j_list.extend( tmp )
			offset += limit
			
	video_list = mc.ListItems()

			
	# ... add live channel
	item = mc.ListItem(mc.ListItem.MEDIA_VIDEO_CLIP)
	item.SetLabel(" --- The Live Channel --- ")
	item.SetThumbnail(default_image)
	item.SetDescription("The GiantBomb Justin.tv channel. Check www.giantbomb.com for updateds on live broadcasts.")
	item.SetPath("http://www.justin.tv/widgets/jtv_player.swf?channel=giantbomb")
	#video_list.append(item)
	
	# ... added archived streams
	for i in range(len(j_list)):
		item = mc.ListItem(mc.ListItem.MEDIA_VIDEO_CLIP)
		try:
		     item.SetLabel(j_list[i]["title"])
		except:
			item.SetLabel("Archived live steam from " + j_list[i]["created_on"])
		item.SetThumbnail(j_list[i]["image_url_medium"])
		item.SetDescription("Archived live steam from " + j_list[i]["created_on"])
		item.SetPath(j_list[i]["video_file_url"])
		video_list.append(item)
	
	# Update the app with the search results
	mc.GetWindow(14000).GetControl(100).SetVisible(True)
	mc.GetWindow(14000).GetControl(200).SetVisible(False)
	mc.GetWindow(14000).GetControl(101).SetVisible(True)
	mc.GetWindow(14000).GetControl(201).SetVisible(False)
	mc.GetWindow(14000).GetList(100).SetItems(video_list)
	mc.GetWindow(14000).GetList(100).SetFocusedItem(0)
	mc.GetWindow(14000).GetLabel(1200).SetLabel("The Justin.tv channel")
	mc.HideDialogWait()	
	mc.GetApp().GetLocalConfig().SetValue("state", "justin")
	
# search the giantbomb database
def search( noDialog = False ):
	mc.GetWindow(14000).GetControl(9012).SetVisible(True)
	mc.GetWindow(14000).GetControl(9013).SetVisible(False)
	mc.GetWindow(14000).GetControl(9011).SetVisible(False)
	mc.GetWindow(14000).GetControl(9014).SetVisible(False)
		
	# Ask for query
	query = ""
	if noDialog is False:
		query = mc.ShowDialogKeyboard("Search the database", "", False)
		mc.GetApp().GetLocalConfig().SetValue("last_query", query)
	else:
		query = mc.GetApp().GetLocalConfig().GetValue("last_query")
	mc.ShowDialogWait()
	
	# Searh the database
	# ... get the search data
	limit = 20
	list = gb.List("search")
	list.extra = "query=" + str(query).replace(" ","_") # spaces = "_"
	list.extra += "&resources=video"
	ok = list.update(0, 0)
	if not ok:
		mc.GetWindow(14000).GetLabel(1200).SetLabel("Search for \"" + str(query) + "\" failed")
		mc.GetWindow(14000).GetList(100).SetContentURL("")
		mc.HideDialogWait()	
		return
	
	# Limit total search results to 100
	over_total = False
	result_limit = 100
	total = list.getTotal()
	if total > result_limit:
		total = result_limit
		over_total = True
	
	video_list = mc.ListItems()	
	for offset in range(0,total,limit):
		ok = list.update(offset, limit)
		if not ok:
			mc.GetWindow(14000).GetLabel(1200).SetLabel("Search for \"" + str(query) + "\" failed")
			mc.GetWindow(14000).GetList(100).SetContentURL("")
			mc.HideDialogWait()	
			return
		
		# ... arrange the data
		for i in range(list.getSize()):
			item = mc.ListItem(mc.ListItem.MEDIA_VIDEO_CLIP)
			item.SetLabel(list.results[i]["name"].encode('utf-8'))
			item.SetThumbnail(list.results[i]["image"]["super_url"].encode('utf-8'))
			item.SetDate(int(list.results[i]["publish_date"][0:4]),int(list.results[i]["publish_date"][8:10]),int(list.results[i]["publish_date"][5:7]))
			item.SetDescription(list.results[i]["deck"].encode('utf-8'))
			item.SetPath("http://media.giantbomb.com/video/" + list.results[i]["url"].encode('utf-8').replace(".mp4","_1500.mp4"))
			video_list.append(item)
	
	# Update the app with the search results
	label = str(list.getTotal()) + " search results for \"" + str(query) + "\""
	if not ok:	
		label = "Search for \"" + str(query) + "\" failed"
	elif over_total is True:
		label += " (Limited to " + str(result_limit) + ")"
		
	mc.GetWindow(14000).GetControl(100).SetVisible(True)
	mc.GetWindow(14000).GetControl(200).SetVisible(False)
	mc.GetWindow(14000).GetControl(101).SetVisible(True)
	mc.GetWindow(14000).GetControl(201).SetVisible(False)
	mc.GetWindow(14000).GetLabel(1200).SetLabel(label)
	mc.GetWindow(14000).GetList(100).SetItems(video_list)
	mc.HideDialogWait()
	mc.GetApp().GetLocalConfig().SetValue("state", "search")	
	
def update_videos():
	mc.GetWindow(14000).GetLabel(1200).SetLabel("Importing video data 0%")
	
	# Init video list setup and get total number of videos
	list = gb.List("videos")
	list.extra = "field_list=deck,image,name,publish_date,site_detail_url,url&sort=publish_date"
	ok = list.update(0,0)
	if ok is False:
		print "ERROR UPDATING VIDEO DATA"
		mc.GetWindow(14000).GetLabel(1200).SetLabel("Error connecting to giantbomb.com")
		return
	
	total = list.getTotal()
	
	videos = []
	limit = 100
	
	# Compare total to local total
	try:
		FILE = open(video_file, 'r+')
		file_content = FILE.read()
		FILE.close()
		offset = json.loads(file_content, object_hook=wm.E('total').as_e)
		
		# Test file integrati
		if offset != len(json.loads(file_content, object_hook=wm.E('videos').as_e)):
			raise ValueError
			
		# Test video filename
		if( file_content.find(".flv") != -1):
			print "OLD FILENAMES"
			raise ValueError
		
	except:
		print "ERROR IN DATA FILE"
		offset = 0
	
	# if no new videos return
	if total == offset:
		mc.GetWindow(14000).GetLabel(1200).SetLabel("Importing video data 100%")
		return
		
	# get old videos from file
	if offset != 0:
		try:
			videos.extend(json.loads(file_content, object_hook=wm.E('videos').as_e))
			
			# Remove videos from the latest date
			last_date = videos[len(videos)-1]["publish_date"][0:10]
			for i in range(len(videos)-1,0,-1):
				if videos[i]["publish_date"][0:10] != last_date:
					break
				del videos[i]
			offset = len(videos)
		
		except:
			print "ERROR IN DATA FILE"
			videos = []
			offset = 0
	
	start_cnt = offset
	total_cnt = total - offset	
	# get the remaning videos
	while (offset < total):
		ok = list.update(offset,limit)
		if ok is False:
			print "ERROR UPDATING VIDEO DATA"
			mc.GetWindow(14000).GetLabel(1200).SetLabel("Error connecting to giantbomb.com")
			return
		
		videos.extend(list.results)
		offset += limit
		i_pct = int(( float(offset-start_cnt) / float(total_cnt))*100.0+0.5)
		if i_pct > 100:
			i_pct = 100
		mc.GetWindow(14000).GetLabel(1200).SetLabel("Importing video data " + str(i_pct) +"%")
		
	# Create json formated video data and write to file
	video_list = { 'total': total, 'videos': videos }
	FILE = open(video_file, 'w')
	FILE.write( json.dumps( video_list ) )
	FILE.close()

	mc.GetWindow(14000).GetLabel(1200).SetLabel("Importing video data 100%")
	
def video( cat = True ):
	mc.ShowDialogWait()
	mc.GetWindow(14000).GetControl(9011).SetVisible(True)
	mc.GetWindow(14000).GetControl(9012).SetVisible(False)
	mc.GetWindow(14000).GetControl(9013).SetVisible(False)
	mc.GetWindow(14000).GetControl(9014).SetVisible(False)
	config = mc.GetApp().GetLocalConfig()
	
	if cat is True:
		# Update
		update_videos()
		mc.GetWindow(14000).GetLabel(1200).SetLabel("Video categories")
		
		# Settings
		SETT = ""
		load_local = False
		# Get settings from web
		try:
			s = urllib.urlopen( settings_url )
			SETT = s.read()
			
			#Check if data is ok
			json.loads(SETT, object_hook=wm.E('categories').as_e)[0]
		
		except:
			print "SETTINGS UPDATE ERROR"
			load_local = True
		
		else:
			print "SETTINGS UPDATE OK"
		
		if load_local is True:
			# Load settings from file
			try:
				# Read settings from local file
				FILE = open( settings_file, 'r+' )
				SETT = FILE.read()
				FILE.close()
				
			except:
				print "SETTINGS FILE ERROR, LOADING BACKUP"
				# Read settings from local backup file
				FILE = open( settings_file, 'r+' )
				SETT = FILE.read()
				FILE.close()
	
			else:
				print "SETTINGS FILE OK"
			
		# Collectiong categori information
		cat = json.loads(SETT, object_hook=wm.E('categories').as_e)
		config.SetValue("cat", str(cat))
		
		catMenu = mc.ListItems()

		for i in range(len(cat)):
			item = mc.ListItem(mc.ListItem.MEDIA_UNKNOWN)
			item.SetLabel(cat[i]["name"].encode('utf-8'))
			item.SetDescription(cat[i]["description"].encode('utf-8'))
			item.SetThumbnail(default_image)
			catMenu.append(item)
		
		mc.GetWindow(14000).GetList(200).SetItems(catMenu)
		mc.GetWindow(14000).GetControl(200).SetFocus()
		mc.GetWindow(14000).GetControl(100).SetVisible(False)
		mc.GetWindow(14000).GetControl(200).SetVisible(True)
		mc.GetWindow(14000).GetControl(101).SetVisible(False)
		mc.GetWindow(14000).GetControl(201).SetVisible(True)
		
	else:
		mc.GetActiveWindow().PushState()
		
		cat_list = mc.GetWindow(14000).GetList(200)
		cat_control = mc.GetWindow(14000).GetControl(200)
		video_control = mc.GetWindow(14000).GetControl(100)
		
		cat = eval( config.GetValue("cat") )
		
		item = cat_list.GetItem(cat_list.GetFocusedItem())
		mc.GetWindow(14000).GetLabel(1200).SetLabel(item.GetLabel())
		cat_control.SetVisible(False)
		video_control.SetVisible(True)
		mc.GetWindow(14000).GetControl(101).SetVisible(True)
		mc.GetWindow(14000).GetControl(201).SetVisible(False)
		
		# Read to the data file
		try:
			FILE = open(video_file, 'r+')
			file_content = FILE.read()
			FILE.close()
			total = json.loads(file_content, object_hook=wm.E('total').as_e)
			videos = json.loads(file_content, object_hook=wm.E('videos').as_e)
			
			# Test file integrati
			if total != len(videos):
				raise ValueError
			
		except:
			print "ERROR IN DATA FILE"
			FILE = open(video_file, 'w')
			FILE.write("")
			FILE.close()
			return
		
		filt = cat[cat_list.GetFocusedItem()]["filters"]
		video_list = mc.ListItems()
		video_count = 0
		for i in range(total-1,0,-1):
			found = False
			name = videos[i]["name"]
				
			# Latest
			if (filt == ["latest_cat"]):
				if (i>total-26):
					found = True
					
			# Custom catagories
			else:
				for x in range(0, len(filt)):
					if( name.find(filt[x]) != -1):
						found = True
						break
			
			if (found is True):
				item = mc.ListItem(mc.ListItem.MEDIA_VIDEO_CLIP)
				item.SetLabel(name.encode('utf-8'))
				item.SetThumbnail(videos[i]["image"]["super_url"].encode('utf-8'))
				item.SetDate(int(videos[i]["publish_date"][0:4]),int(videos[i]["publish_date"][8:10]),int(videos[i]["publish_date"][5:7]))
				item.SetDescription(videos[i]["deck"].encode('utf-8'))
				item.SetPath("http://media.giantbomb.com/video/" + videos[i]["url"].encode('utf-8').replace(".mp4","_1500.mp4"))
				video_list.append(item)
				
		mc.GetWindow(14000).GetList(100).SetItems(video_list)
		mc.GetWindow(14000).GetControl(100).SetFocus()
		
	mc.HideDialogWait()	
	mc.GetApp().GetLocalConfig().SetValue("state", "video")

